﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TireService.Data;
using DevExpress.Web.ASPxCallback;
using System.Configuration;

namespace TireService.Web.View.ServiceView
{
    public partial class PlanningFollowup : System.Web.UI.Page
    {

        #region Public Properties

        public List<int> MarkedServiceDetails
        {
            get
            {
                if (ViewState["_markedservicedetails"] != null)
                    return (List<int>)ViewState["_markedservicedetails"];
                else
                    return null;
            }
            set
            {
                ViewState["_markedservicedetails"] = value;
            }
        }

        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            if (Page.IsPostBack != true)
            {
                
            }

            // Bind container data to gridview
            BindServiceCarScheduleCustomerFollowup(db);

            // Change gridview pagesize based on dropdownlist
            gvPlanningFollowup.SettingsPager.PageSize = Convert.ToInt32(ddlPageSize.SelectedValue);

            // Dispose connection to database
            db.Dispose();
        }

        /// <summary>
        /// Function that bind servicecarschedule that has not been comfirmed by customer on schedules that is not completed
        /// </summary>
        /// <param name="db">Connection to database</param>
        private void BindServiceCarScheduleCustomerFollowup(TireServiceDB db)
        {
            // TODO: Evaluate below - related to adding tasks
            //gvPlanningFollowup.DataSource = db.ServiceCarScheduleDetailViews.Where(p => p.ScheduleDetailTypeId == (int)Shared.ScheduleDetailType.TireChange & p.CustomerConfirmed == false & p.WorkCompleted == false).OrderBy(p => p.ScheduleDate).ToList();
            gvPlanningFollowup.DataSource = db.ServiceCarScheduleDetailViews.Where(p => p.ScheduleDetailTypeId == (int)Shared.ScheduleDetailType.ServiceDrive & p.CustomerConfirmed == false & p.WorkCompleted == false).OrderBy(p => p.ScheduleDate).ToList();
            gvPlanningFollowup.DataBind();

            GroupOrderData(Convert.ToInt32(ddlView.SelectedValue));
        }

        #region Private Functions

        /// <summary>
        /// Function that set UI to mark-as-completed mode of all selected servicescheduledetails in gridview
        /// </summary>
        private void MarkAsCustomerApproved()
        {
            List<object> keyValues = gvPlanningFollowup.GetSelectedFieldValues("ServiceCarScheduleDetailId");

            if (keyValues.Count != 0)
            {
                TireServiceDB db = new TireServiceDB();

                // Set selected scheduledetails as confirmed by customer
                foreach (object key in keyValues)
                {
                    ServiceCarScheduleDetail detail = db.GetServiceCarScheduleDetail(Convert.ToInt32(key.ToString()));

                    detail.CustomerConfirmed = true;
                }

                // Commit changes to database
                db.SubmitChanges();

                // Refresh page 
                BindServiceCarScheduleCustomerFollowup(db);

                // Dispose database connection
                db.Dispose();
            }
            else
            {
                throw new ArgumentException("Ingen planlagte hjulskift valgt.");
            }
        }

        /// <summary>
        /// Function that sends confirmation email to selected customer
        /// </summary>
        /// <param name="db">Connection to database</param>
        /// <param name="ServiceCarScheduleDetailId">Id on booking to send email for</param>
        private void SendConfirmationEmailToSelected(TireServiceDB db, int ServiceCarScheduleDetailId)
        {
            // Fecth detail
            ServiceCarScheduleDetailView detail = db.ServiceCarScheduleDetailViews.SingleOrDefault(p => p.ServiceCarScheduleDetailId == ServiceCarScheduleDetailId);

            if (detail != null)
            {
                //if (detail.ScheduleDetailTypeId == (int)Shared.ScheduleDetailType.TireChange)
                if (detail.ScheduleDetailTypeId == (int)Shared.ScheduleDetailType.ServiceDrive)
                {
                    // Send email
                    SendConfirmationEmail(db, detail);
                }
            }
        }

        /// <summary>
        /// Function that sends email to customer for a specific servicedetail
        /// </summary>
        /// <param name="db">Database connection</param>
        /// <param name="scheduledetail">Servicedetail</param>
        private void SendConfirmationEmail(TireServiceDB db, ServiceCarScheduleDetailView scheduledetail)
        {
            string CustomerApprovalLink = ConfigurationManager.AppSettings["CustomerConfirmationURL"].ToString() + "?ApprovalId=" + scheduledetail.DetailGuid.ToString() + "&CID=" + scheduledetail.CustomerId.ToString();
            string CustomerDisapprovalLink = ConfigurationManager.AppSettings["CustomerConfirmationURL"].ToString() + "?ApprovalId=" + scheduledetail.DetailGuid.ToString() + "&Approve=false&CID=" + scheduledetail.CustomerId.ToString();

            EmailNotificationServices emailService = new EmailNotificationServices();
            emailService.BookServiceDrive_SendCustomerEmail(scheduledetail.Email, scheduledetail.Name, db.GetCarRegistrationNumber(Convert.ToInt32(scheduledetail.CarId)), scheduledetail.TireTypeDescription, scheduledetail.ScheduleDate.ToShortDateString(), scheduledetail.StartTime.ToString() + "-" + scheduledetail.EndTime.ToString(), scheduledetail.ToAddress, scheduledetail.ToZipCode, scheduledetail.ToCity, scheduledetail.CustomerId.ToString(), scheduledetail.SubscriptionId.ToString(), scheduledetail.CustomerSubscriptionId.ToString(), CustomerApprovalLink, CustomerDisapprovalLink);

            //// Send email
            //SendEmail(scheduledetail.Email, scheduledetail.Name, db.GetCarRegistrationNumber(Convert.ToInt32(scheduledetail.CarId)), scheduledetail.TireTypeDescription, scheduledetail.ScheduleDate.ToShortDateString(), scheduledetail.StartTime.ToString() + "-" + scheduledetail.EndTime.ToString(), scheduledetail.ToAddress, scheduledetail.ToZipCode, scheduledetail.ToCity, scheduledetail.DetailGuid.ToString(), scheduledetail.CustomerId.ToString(), scheduledetail.SubscriptionId.ToString(), scheduledetail.CustomerSubscriptionId.ToString());

            // Update serviceschedule detail
            ServiceCarScheduleDetail updatescheduledetail = db.GetServiceCarScheduleDetail(scheduledetail.ServiceCarScheduleDetailId);
            updatescheduledetail.CustomerEmailSendCount = updatescheduledetail.CustomerEmailSendCount + 1;
        }

        /// <summary>
        /// Function that change grouping in order gridview
        /// </summary>
        /// <param name="ViewIndex">Integer setting the grouping mode</param>
        protected void GroupOrderData(int ViewIndex)
        {
            gvPlanningFollowup.ClearSort();
            gvPlanningFollowup.GroupSummary.Clear();
            switch (ViewIndex)
            {
                case 0:

                    gvPlanningFollowup.GroupBy(gvPlanningFollowup.Columns["ScheduleDate"]);
                    gvPlanningFollowup.GroupBy(gvPlanningFollowup.Columns["ServiceCarId"]);

                    break;
                case 1:
                    gvPlanningFollowup.GroupBy(gvPlanningFollowup.Columns["ContainerNumber"]);
                    gvPlanningFollowup.GroupBy(gvPlanningFollowup.Columns["ScheduleDate"]);

                    break;
            }
            gvPlanningFollowup.ExpandAll();
        }

        /// <summary>
        /// Function that change confirmation on servicedetail for customer
        /// </summary>
        /// <param name="db">Connection to database</param>
        /// <param name="ServiceCarScheduleDetailId">Id on booking to set as customer confirmed/not confirmed</param>
        /// <param name="CustomerConfirmed">True/False value indicating if customer confirmed booking</param>
        private void CustomerConfirmed(TireServiceDB db, int ServiceCarScheduleDetailId, bool CustomerConfirmed)
        {
            // Fecth detail to update
            ServiceCarScheduleDetail detail = db.GetServiceCarScheduleDetail(ServiceCarScheduleDetailId);

            if (detail != null)
            {
                if (detail.ScheduleDetailTypeId == (int)Shared.ScheduleDetailType.ServiceDrive)
                {
                    // Update detail
                    detail.CustomerConfirmed = CustomerConfirmed;
                }
            }
        }

        #endregion

        #region Control Functions

        /// <summary>
        /// Button function for export of gridview
        /// </summary>
        protected void btnExport_Click(object sender, EventArgs e)
        {
            if (ddlExport.Value == "0")
            {
                gvExport.WritePdfToResponse();
            }

            if (ddlExport.Value == "1")
            {
                gvExport.WriteXlsToResponse();
            }

            if (ddlExport.Value == "2")
            {
                gvExport.WriteCsvToResponse();
            }

            if (ddlExport.Value == "3")
            {
                gvExport.WriteRtfToResponse();
            }
        }

        /// <summary>
        /// Dropdown list function that change gridview grouping when selected item is changed
        /// </summary>
        protected void ddlView_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Group data
            GroupOrderData(Convert.ToInt32(ddlView.SelectedValue));
        }

        #endregion


        #region GridView Functions

        /// <summary>
        /// Gridview function that handles edit selection
        /// </summary>
        protected void gvPlanningFollowup_CustomButtonCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomButtonCallbackEventArgs e)
        {
            if (e.ButtonID == "Approve")
            {
                try
                {
                    // Get ServiceCarScheduleDetailId
                    object cellServiceCarScheduleDetailId = gvPlanningFollowup.GetRowValues(e.VisibleIndex, "ServiceCarScheduleDetailId");

                    TireServiceDB db = new TireServiceDB();

                    ServiceCarScheduleDetail detail = db.GetServiceCarScheduleDetail(Convert.ToInt32(cellServiceCarScheduleDetailId));

                    detail.CustomerConfirmed = true;

                    // Commit changes to database
                    db.SubmitChanges();

                    // Refresh page 
                    BindServiceCarScheduleCustomerFollowup(db);

                    // Dispose database connection
                    db.Dispose();
                }
                catch (Exception ex)
                {
                    //if ((ex) is ArgumentException)
                    //{
                    //    // User error - arguments not valid - show error message
                    //    lMessage.Text = ((ArgumentException)ex).Message;
                    //}
                    //else
                    //{
                    //    // System error - show general error message
                    //    lMessage.Text = "Fejl opstod - venligst prøv igen";
                    //}
                }
            }
        }

        /// <summary>
        /// Gridview function that change field data for unbound fields
        /// </summary>
        protected void gvPlanningFollowup_CustomUnboundColumnData(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewColumnDataEventArgs e)
        {
            // Format UnBoundColumn TireDimensions: Show TireDimensions
            if (e.Column.FieldName == "TireDimensions")
            {
                // Get dimensions
                string width = Convert.ToString(e.GetListSourceFieldValue("Width"));
                string height = Convert.ToString(e.GetListSourceFieldValue("Height"));
                string size = Convert.ToString(e.GetListSourceFieldValue("Size"));

                // Change field value
                e.Value = width + " / " + height + " " + size;
            }
        }

        protected void callBackMarkSelectedAsApproved_Callback(object sender, CallbackEventArgs e)
        {
            // Send email to selected customers
            string[] param = e.Parameter.Split(',');

            // Instantiate database
            TireServiceDB db = new TireServiceDB();

            for (int i = 0; i < param.Length; i++)
            {
                CustomerConfirmed(db, Convert.ToInt32(param[i]), true);
            }

            // Commit changes to database
            db.SubmitChanges();

            // Rebind gridview
            BindServiceCarScheduleCustomerFollowup(db);

            // Dispose database connection
            db.Dispose();
        }

        /// <summary>
        /// Callback function that handles approval and blocking of dayplan records
        /// </summary>
        protected void callBackManageCustomerApproval_Callback(object sender, CallbackEventArgs e)
        {
            // Get values (0: Actionparameter, 1-X: Array of servicecarscheduledetailid's)
            string[] param = e.Parameter.Split(',');

            // Instantiate database
            TireServiceDB db = new TireServiceDB();

            // Validate action to take
            if (Convert.ToString(param[0]) == "RequestApproval")
            {
                for (int i = 1; i < param.Length; i++)
                {
                    SendConfirmationEmailToSelected(db, Convert.ToInt32(param[i]));
                }
            }

            // Commit changes to database
            db.SubmitChanges();

            // Dispose database connection
            db.Dispose();
        }

        /// <summary>
        /// Gridview function that runs when user has confirmed to delete record
        /// </summary>
        protected void gvPlanningFollowup_RowDeleting(object sender, DevExpress.Web.Data.ASPxDataDeletingEventArgs e)
        {
            //// Delete record
            //try
            //{
            //    e.Cancel = true;

            //    // Instantiate database connection
            //    TireServiceDB db = new TireServiceDB();

            //    int ServiceCarScheduleDetailId = Convert.ToInt32(e.Keys[0]);

            //    // Fetch scheduledetail
            //    ServiceCarScheduleDetail scheduledetail = db.GetServiceCarScheduleDetail(ServiceCarScheduleDetailId);

            //    if (scheduledetail.WorkCompleted)
            //    {
            //        throw new ArgumentException("Hjulskift kan ikke slettes, da opgave er angivet som udført.");
            //    }

            //    // Fetch schedule 
            //    ServiceCarSchedule schedule = db.GetServiceCarSchedule(scheduledetail.ServiceCarId, scheduledetail.ScheduleDate);

            //    if (schedule == null)
            //    {
            //        throw new ArgumentException("Valgt plan for hjulskift kunne ikke findes.");
            //    }

            //    // Fetch all scheduledetails for serviceschedule
            //    List<ServiceCarScheduleDetail> schedulelist = schedule.ServiceCarScheduleDetails.OrderBy(p => p.SequenceNumber).ToList();

            //    //// Delete tasklist
            //    //db.ServiceCarScheduleTasklists.DeleteAllOnSubmit(scheduledetail.ServiceCarScheduleTasklists);

            //    // Delete scheduledetail
            //    db.ServiceCarScheduleDetails.DeleteOnSubmit(scheduledetail);

            //    // Reorder
            //    if (schedulelist.Count == 1)
            //    {
            //        // Delete schedule
            //        db.ServiceCarSchedules.DeleteOnSubmit(schedule);
            //    }
            //    else
            //    {
            //        // Placeholder for new starttime
            //        TimeSpan newstarttime = (TimeSpan)scheduledetail.StartTime;

            //        foreach (ServiceCarScheduleDetail selectedscheduledetail in schedulelist)
            //        {
            //            if (selectedscheduledetail.SequenceNumber > scheduledetail.SequenceNumber)
            //            {
            //                // Update sequence number
            //                selectedscheduledetail.SequenceNumber = selectedscheduledetail.SequenceNumber - 1;

            //                // Calculate new start-/end times
            //                TimeSpan time = (TimeSpan)(selectedscheduledetail.EndTime - selectedscheduledetail.StartTime);
            //                selectedscheduledetail.StartTime = newstarttime;
            //                selectedscheduledetail.EndTime = newstarttime.Add(time);

            //                // Update placeholder for re-ordering of sequencenumber
            //                newstarttime = (TimeSpan)selectedscheduledetail.EndTime;
            //            }
            //        }
            //    }

            //    // Change status on car
            //    Car car = db.GetCar(Convert.ToInt32(scheduledetail.CarId));

            //    if (car != null)
            //    {
            //        car.CarStatusId = (int)Shared.CarStatus.NeedsTireChanged;
            //    }
            //    else
            //    {
            //        throw new ArgumentException("Fejl opstod - valgt bil og hjulsæt kunne ikke findes. Prøv igen eller kontakt IT administrator.");
            //    }

            //    // Commit changes to database
            //    db.SubmitChanges();

            //    // Rebind gridviews
            //    BindServiceCarScheduleCustomerFollowup(db);

            //    // Dipose database connection
            //    db.Dispose();

            //    // Change message
            //    lMessage.Text = "Planlagt hjulskift blev slettet";
            //}
            //catch (Exception ex)
            //{
            //    if ((ex) is ArgumentException)
            //    {
            //        // User error - arguments not valid - show error message
            //        lMessage.Text = ((ArgumentException)ex).Message;
            //    }
            //    else
            //    {
            //        // System error - show general error message
            //        lMessage.Text = "Fejl opstod - venligst prøv igen";
            //    }
            //}
            //finally
            //{
            //    // Update message panel
            //    upMessage.Update();
            //}
        }

        #endregion
    }
}